package batch.execution;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

import batch.monitor.server.JMXAgent;

@SuppressWarnings("rawtypes")
public class RunDefaultBSvc implements Tasklet{
	private AbstractBusiness biz;
	private AbstractVO svo;
	private String filePath;
	private List<String> cfgList = new ArrayList<String>();
	
	private static final int IDLE_TIME = 1*2000;
	private static final int START_IDLE_TIME = 1*1000;

	@Override
	public void execute(Map<String,String> map) {
		try {
			init();
			
			cfgList = scanFile(getFilePath());
			
			biz = getBiz();
			svo = getSVO();
			svo.setBatchDescription(map.get("batchDescription"));
			svo.setBatchCfgName(map.get("batchCfgName"));
			
			List list = invokeSelectListMethod();
			initManagement(list.size(), svo.getBatchDescription(), svo.getBatchCfgName());
			
			for(int i = 0 ; i < list.size() ; i++) {
				AbstractVO vo = (AbstractVO) list.get(i);
				JMXAgent.getDefault().getBatchStats().nextManage(vo);
				invokeStepMethod(vo);
			}
		} catch(Exception e) { throw new RuntimeException(e);}
	}
	
	public void init() throws Exception {
		Thread.sleep(START_IDLE_TIME);
		System.out.println("start!!!!");
	}
	
	private List<String> scanFile(String filePath) throws FileNotFoundException {
		List<String> list = new ArrayList<String>();
		FileInputStream fis = new FileInputStream(filePath);
		Scanner scanner = new Scanner(fis);
		while (scanner.hasNextLine()) {
			list.add(scanner.nextLine());
		}
		return list;
	}

	private List invokeSelectListMethod() throws Exception {
		String[] method = cfgList.get(0).split(":");
		return (List) biz.getClass().getMethod(method[1], Class.forName(method[2])).invoke(biz, svo);
	}

	private void initManagement(int fullCount, String batchDescription, String batchCfgName) {
		try {
			JMXAgent.getDefault().getBatchStats().startManage(fullCount, batchDescription, batchCfgName);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	private AbstractVO getSVO() throws Exception {
		String[] cfg = cfgList.get(0).split(":");
		Class voClass = Class.forName(cfg[2]);
		return (AbstractVO) voClass.newInstance();
	}

	private AbstractBusiness getBiz() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		String[] cfg = cfgList.get(0).split(":");
		Class bizClass = Class.forName(cfg[0]);
		return (AbstractBusiness) bizClass.newInstance();
	}

	private void invokeStepMethod(AbstractVO vo) throws Exception {
		for(int i = 1; i < cfgList.size(); i++) {
			Thread.sleep(IDLE_TIME);
			String[] cfg = cfgList.get(i).split(":");
			biz.getClass().getMethod(cfg[1], Class.forName(cfg[2])).invoke(biz, vo);
		}
	}

	public void setFilePath(String filePath) {
		this.filePath = filePath;
	}
	public String getFilePath() {
		return filePath;
	}

}
